package com.lqwu.mallchatserver.chat.service.impl;

import com.lqwu.mallchatserver.chat.model.dto.MemberReq;
import com.lqwu.mallchatserver.chat.service.ChatService;
import com.lqwu.mallchatserver.chat.service.cache.RoomCache;
import com.lqwu.mallchatserver.chat.service.strategy.MsgHandlerFactory;
import com.lqwu.mallchatserver.chat.strategy.msg.AbstractMsgHandler;
import com.lqwu.mallchatserver.common.domain.enums.NormalOrNoEnum;
import com.lqwu.mallchatserver.common.domain.vo.request.CursorPageBaseReq;
import com.lqwu.mallchatserver.common.domain.vo.response.CursorPageBaseResp;
import com.lqwu.mallchatserver.common.event.MessageSendEvent;
import com.lqwu.mallchatserver.common.service.cache.RoomGroupCache;
import com.lqwu.mallchatserver.common.utils.AssertUtil;
import com.lqwu.mallchatserver.user.model.dto.ChatMessageReq;
import com.lqwu.mallchatserver.user.model.entry.*;
import com.lqwu.mallchatserver.user.service.GroupMemberService;
import com.lqwu.mallchatserver.user.service.RoomFriendService;
import com.lqwu.mallchatserver.user.service.RoomGroupService;
import com.lqwu.mallchatserver.websocket.model.vo.response.data.ChatMemberResp;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ChatServiceImpl implements ChatService {
    @Resource
    private RoomCache roomCache;
    @Resource
    private RoomFriendService roomFriendService;
    @Resource
    private RoomGroupCache roomGroupCache;
    @Resource
    private GroupMemberService groupMemberService;
    @Resource
    private ApplicationEventPublisher publisher;

    // todo
    /**
     * 发送消息
     * @param chatMessageReq
     * @param uid
     */
    @Override
    @Transactional
    public Long sendMsg(ChatMessageReq chatMessageReq, Long uid) {
        // 1.检验用户是否能发
        check(chatMessageReq,uid);
        // 2.根据消息类型获取策略
        AbstractMsgHandler<?> msgHandler = MsgHandlerFactory.getStrategyNoNull(chatMessageReq.getMsgType());
        Long msgId = msgHandler.checkAndSaveMsg(chatMessageReq, uid);
        // 3.发送消息事件
        publisher.publishEvent(new MessageSendEvent(this,msgId));
        return msgId;
    }

    /**
     * 游标分页获取群成员列表
     * @param request
     * @param memberUidList
     * @return
     */
    @Override
    public CursorPageBaseResp<ChatMemberResp> getMemberPage(MemberReq request, List<Long> memberUidList) {
        // todo 游标分页获取群成员列表
//        Pair<ChatActiveStatusEnum, String> pair = ChatMemberHelper.getCursorPair(request.getCursor());
//        ChatActiveStatusEnum activeStatusEnum = pair.getKey();
//        String timeCursor = pair.getValue();
//        List<ChatMemberResp> resultList = new ArrayList<>();//最终列表
//        Boolean isLast = Boolean.FALSE;
//        if (activeStatusEnum == ChatActiveStatusEnum.ONLINE) {//在线列表
//            CursorPageBaseResp<User> cursorPage = userDao.getCursorPage(memberUidList, new CursorPageBaseReq(request.getPageSize(), timeCursor), ChatActiveStatusEnum.ONLINE);
//            resultList.addAll(MemberAdapter.buildMember(cursorPage.getList()));//添加在线列表
//            if (cursorPage.getIsLast()) {//如果是最后一页,从离线列表再补点数据
//                activeStatusEnum = ChatActiveStatusEnum.OFFLINE;
//                Integer leftSize = request.getPageSize() - cursorPage.getList().size();
//                cursorPage = userDao.getCursorPage(memberUidList, new CursorPageBaseReq(leftSize, null), ChatActiveStatusEnum.OFFLINE);
//                resultList.addAll(MemberAdapter.buildMember(cursorPage.getList()));//添加离线线列表
//            }
//            timeCursor = cursorPage.getCursor();
//            isLast = cursorPage.getIsLast();
//        } else if (activeStatusEnum == ChatActiveStatusEnum.OFFLINE) {//离线列表
//            CursorPageBaseResp<User> cursorPage = userDao.getCursorPage(memberUidList, new CursorPageBaseReq(request.getPageSize(), timeCursor), ChatActiveStatusEnum.OFFLINE);
//            resultList.addAll(MemberAdapter.buildMember(cursorPage.getList()));//添加离线线列表
//            timeCursor = cursorPage.getCursor();
//            isLast = cursorPage.getIsLast();
//        }
//        // 获取群成员角色ID
//        List<Long> uidList = resultList.stream().map(ChatMemberResp::getUid).collect(Collectors.toList());
//        RoomGroup roomGroup = roomGroupDao.getByRoomId(request.getRoomId());
//        Map<Long, Integer> uidMapRole = groupMemberDao.getMemberMapRole(roomGroup.getId(), uidList);
//        resultList.forEach(member -> member.setRoleId(uidMapRole.get(member.getUid())));
//        //组装结果
//        return new CursorPageBaseResp<>(ChatMemberHelper.generateCursor(activeStatusEnum, timeCursor), isLast, resultList);
        return null;
    }

    /**
     * 进行用户的检查
     * @param request
     * @param uid
     */
    private void check(ChatMessageReq request, Long uid) {
        // 1.从缓存中获取房间信息
        Room room = roomCache.get(request.getRoomId());
        // 2.判断是否为总群聊
        if (room.isHotRoom()){
            return;
        }
        // 3.好友聊天校验
        if (room.isRoomFriend()){
            // 检查是否被拉黑
            RoomFriend roomFriend = roomFriendService.lambdaQuery()
                    .eq(RoomFriend::getRoomId, request.getRoomId())
                    .one();
            AssertUtil.isTrue(roomFriend.getStatus().equals(NormalOrNoEnum.NOT_NORMAL.getStatus()),"您被拉黑了");
            // 检查是否是本人
            AssertUtil.isTrue(roomFriend.getUid1().equals(uid) || roomFriend.getUid2().equals(uid),"您没有权限发送消息");
        }
        // 4.群聊校验
        if (room.isRoomGroup()){
            // 检查是否是群成员
            RoomGroup roomGroup = roomGroupCache.get(request.getRoomId());
            GroupMember member = groupMemberService.getMember(roomGroup.getId(), uid);
            AssertUtil.isNotEmpty(member,"您已经被移除该群");
        }
    }
}
